﻿Option Strict On

Imports System.Windows.Forms

''' <summary>
''' Klasse zum verarbeiten von Exceptions die beim Zuweisen von Werten durch Databindings entstehen.
''' </summary>
''' <autor>Jens Blawatt</autor>
''' <remarks>Wenn während des Zuweisens von Werten über eine Property durch das Databinding ein Fehler auftritt, 
''' kann das Control nicht verlassen werden. Welcher Fehler aber auftritt kann an der Oberfläsche nicht erkannt
''' werden. In dieser Klasse können Controls registriert werden, an denen dann ein System.Windows.Forms.ErrorProvider 
''' mit der jeweiligen Fehlermeldung angezeigt werden.</remarks>
Public Class ErrorProviderManager


    ''' <summary>
    ''' Die Liste der bisher erzeugten und angezeigten System.Windows.Forms.ErrorProvider
    ''' </summary>
    Private _errors As Dictionary(Of System.Windows.Forms.Control, System.Windows.Forms.ErrorProvider)


    ''' <summary>
    ''' Erstellt eine neue Instanz des ErrorProviderManagers
    ''' </summary>
    Public Sub New()
        _errors = New Dictionary(Of System.Windows.Forms.Control, System.Windows.Forms.ErrorProvider)
    End Sub


    ''' <summary>
    ''' Registriert ein Control zur Überwachung auf die Entstehung von Exceptions während des Databinding.
    ''' </summary>
    ''' <param name="c">Das zu registrierende Control</param>
    ''' <param name="boundProperty">Die Property des Controls an die gebunden wurde.</param>
    ''' <remarks></remarks>
    Public Sub RegisterControl(ByVal c As Control, ByVal boundProperty As String)
        AddHandler c.DataBindings(boundProperty).BindingComplete, AddressOf BindingCompleteEventHandler
    End Sub

    ''' <summary>
    ''' Der Eventhandler der nach Fertigstellung des Bindings aufgerufen wird.
    ''' </summary>
    ''' <param name="sender">Das Binding Objekt aus dem Control</param>
    ''' <param name="e">Die Eventparameter aus der Binding Aktion</param>
    Private Sub BindingCompleteEventHandler(ByVal sender As Object, ByVal e As BindingCompleteEventArgs)

        ' das objekt in den richtigen typ casten
        Dim bindingSender As Binding = CType(sender, Binding)

        ' wenn ein fehler während des bindings aufgetreten ist
        If Not (e.BindingCompleteState = BindingCompleteState.Success) Then

            ' erstellen eines neuen error providers
            Dim errorProvider As New ErrorProvider

            ' wenn schn ein errorprovider erstellt wurde, wird der genommen
            If _errors.ContainsKey(bindingSender.Control) Then _
                errorProvider = _errors(bindingSender.Control)

            ' den fehler zuweisen und am control anzeigen
            errorProvider.SetError(bindingSender.Control, e.ErrorText)

            ' den erzeugten errorprovider zwischenspeichern damit der fehler 
            ' später wieder entfernt werden kann
            _errors(bindingSender.Control) = errorProvider
        Else
            ' wenn kein fehler entstanden ist wird geprüft ob für das control 
            ' schon ein errorprovider angezeugt wurde. wenn das so ist wird
            ' die anzeige des fehlers zurückgesetzt.
            If _errors.ContainsKey(bindingSender.Control) Then
                _errors(bindingSender.Control).Clear()
            End If
        End If

    End Sub

End Class
